package com.cafe.case1;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;
/**
 * @author Cafe
 * 2024/6/19 20:59
 */


/**
 * @author Cafe
 * 2024/6/13 21:21
 */
public class KeyUtil {

    private static final String ALGORITHMS = "RSA";


    public static KeyHolder genKey() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        String publicKeyStr = Base64.encodeBase64String(keyPair.getPublic().getEncoded());
        String privateKeyStr = Base64.encodeBase64String(keyPair.getPrivate().getEncoded());

        System.out.println("公钥：" + publicKeyStr);
        System.out.println("私钥：" + privateKeyStr);
        return new KeyHolder(publicKeyStr, privateKeyStr);
    }

    /**
     * @param content          未加密的字符串
     * @param publicKeyEncoded 公钥
     * @return
     * @throws Exception
     */
    public static String encrypt(String content, byte[] publicKeyEncoded) throws Exception {
        // 创建key的工厂
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHMS);
        // 创建 已编码的公钥规格
        X509EncodedKeySpec encPubKeySpec = new X509EncodedKeySpec(publicKeyEncoded);
        // 获取指定算法的密钥工厂, 根据 已编码的公钥规格, 生成公钥对象
        PublicKey publicKey = keyFactory.generatePublic(encPubKeySpec);
        // 获取指定算法的密码器
        Cipher cipher = Cipher.getInstance(ALGORITHMS);
        // 初始化密码器（公钥加密模型）
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        // 加密数据, 返回加密后的密文
        byte[] cipherData = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        // 采用base64算法进行转码,避免出现中文乱码
        return Base64.encodeBase64String(cipherData);
    }

    /**
     * @param encodeEncryptString 未解密的字符串
     * @param privateKeyEncoded   私钥
     * @return
     * @throws Exception
     */
    public static String decrypt(String encodeEncryptString, byte[] privateKeyEncoded) throws Exception {
        // 创建key的工厂
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHMS);
        // 创建 已编码的私钥规格
        PKCS8EncodedKeySpec encPriKeySpec = new PKCS8EncodedKeySpec(privateKeyEncoded);
        // 获取指定算法的密钥工厂, 根据 已编码的私钥规格, 生成私钥对象
        PrivateKey privateKey = keyFactory.generatePrivate(encPriKeySpec);
        // 获取指定算法的密码器
        Cipher cipher = Cipher.getInstance(ALGORITHMS);
        // 初始化密码器（私钥解密模型）
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        // 解密数据, 返回解密后的明文
        byte[] plainData = cipher.doFinal(Base64.decodeBase64(encodeEncryptString));
        // 采用base64算法进行转码,避免出现中文乱码
        return new String(plainData, StandardCharsets.UTF_8);
    }


    public static void main(String[] args) throws Exception {
        KeyHolder keyHolder = genKey();
        String message = "{'oper':'add','param1':11,'param2':22}";
        System.out.println("-----------------原始信息------------------");
        System.out.println(message);
        String encrypt = encrypt(message, Base64.decodeBase64(keyHolder.getPublicKey()));

        //------------------------RSA算法解密
        String decrypt = decrypt(encrypt, Base64.decodeBase64(keyHolder.getPrivateKey()));

        System.out.println("-----------------加密------------------");
        System.out.println(encrypt);
        System.out.println("-----------------解密------------------");
        System.out.println(decrypt);
    }
}

